/* $Header: display.c,v 2.5 04/04/21 10:40:10 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/*                                                                     */
/* MODULE NAME:  display.c - keyboard display routines                 */
/* ============                                                        */
/*                                                                     */
/* Author: Sue Merkel                                                  */
/*         John DeGood (extensive changes - May 92)                    */
/*                                                                     */
/* MODULE PURPOSE:  This module contains functions to output chars to  */
/*                  the keyboard display and utilities to write to     */
/*                  the buffers which then get output to the display.  */
/*                                                                     */
/***********************************************************************/

/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include  <typedefs.h>
#include  <p_wkfile.h>
#include  <wkfile.h>
#include  <ramps.h>
#include  <zone_config.h>
#include  <zone_status.h>
#include  <status.h>
#include  <display.h>
#include  <iomap.h>
#include  <regs.h>
#include  <stdarg.h>
#include  <messages.h>
#include  <msg.h>

/*****************************/
/*   LOCAL PROTOTYPES        */
/*****************************/

static void DoDisplayRamString(BIT8 * ram_string, va_list *pap);
static void DoDisplayRamStringAppend(BIT8 * ram_string, va_list *pap);
static INT16 NotFull(INT16 j);
void        EnableErrorTimeout (void);

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/

DISP_IMAGE  External_Image;
BIT8        External_Display;


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/

/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/

/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

#pragma SECTION PROG = SysCode

/***********************************************************************/
/* FUNCTION:  OutputCharToDisplay                                      */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function outputs a character to the keyboard         */
/*           display. It is called by the Hz512 function.              */
/*                                                                     */
/*           NOTE: Blinking is achieved by fillling the Disp_Image     */
/*                 buffer field called normal_image with a string or   */
/*                 single character to blink, and the blink_image with */
/*                 the appropriate number of matching blanks. For non- */
/*                 blinking strings, the blink_image is simply a       */
/*                 duplicate of the normal_image. This is the assump-  */
/*                 tion for this routine to handle blinking.           */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

/*
** During each 512 Hz interrupt 2 characters are output, so it takes
** 40/512 seconds to update the entire 80 char display.
**
** SWITCH_RATE is how many times the entire display is updated
** before switching between the normal image and the blink image.
** For example, if SWITCH_RATE is 6 the display will switch about
** every 0.5 sec.
**
** For each line that contains alternating information we add
** ALTERNATING_LINE_DELAY counts before switching between the
** images.  This gives the user extra time to absorb the changing
** information.
*/

#define SWITCH_RATE             4       /* approx 0.3 second */
#define ALTERNATING_LINE_DELAY  13      /* approx 1.0 second */

void OutputCharToDisplay()
{
/*--------begin change by wangwei----------*/
  printf("call OutputCartToDisplay\n");
//    static INT16 SwitchRate;
//    INT16 i, j;
//    BIT8 c;
// 
//    /* First check to make sure the display is not busy. */
//    if ((*PACTL & 0x08) == 0)
//    {
//        /* Uses parallel transmission.
//           The count field controls the ratio for blinking on/off.  For
//           example, for a 75% duty cycle (on 75%, off 25%), display the
//           character from the normal_image for count <= 5 and the
//           blink_image for count = 6,7.  Note that as mentioned above,
//           if the blink_image contains the same characters as the
//           normal_image, no blinking will occur, and the count variable
//           is meaningless.  The offset variable is used to step through
//           the display buffers.  All of the variables used are
//           initialized in InitializeDisplay, which is called at startup.
//        */
// 
//       if (External_Display)
//       {
//          /* Display the buffer used by external (data comm) sources */
// 
//          if (External_Image.count < SwitchRate)
//             DISPLAY = (INT8)External_Image.normal_image[External_Image.offset];
//          else
//             DISPLAY = (INT8)External_Image.blink_image[External_Image.offset];
// 
//        /* Increment the offset to get to the next character in the
//           buffer to display.  When the offset is equal to the size of
//           the buffer to be displayed, we have reached the end of the
//           information to be transmitted to the display.  Reset the
//           offset to zero, and increment the count variable which
//           controls the blink ratio.  Reset the count variable to zero
//           when appropriate.  */
// 
//          if (++External_Image.offset >= DISPLAY_LENGTH)
//          {
//             External_Image.offset = 0;
// 
//             /*
//             ** Calculate SwitchRate based on display content.
//             ** We do this here as we can't afford the overhead for every character!
//             */
// 
//             SwitchRate = SWITCH_RATE;
// 
//             /* do for each display line */
//             for (i = 0; i < 4; i++)
//             {
//                /* do for each char in display line */
//                for (j = (i * DISPLAY_LINE_LENGTH); j < ((i + 1) * DISPLAY_LINE_LENGTH); j++)
//                {
//                   c = External_Image.blink_image[j];
// 
//                   /* is this an alternating character */
//                   if ((c != ' ') && (c != External_Image.normal_image[j]))
//                   {
//                         /* if we find an alternating character anywhere in the line, slow down the switch rate */
//                         SwitchRate += ALTERNATING_LINE_DELAY;
//                         break;  /* no need to look further */
//                   }
//                }
//             }
// 
//             /* have we finished this switch cycle? */
//             if (++External_Image.count >= (SwitchRate * 2))
//             {
//                External_Image.count = 0;
//             }
//          }
//       }
//       else   /* Normal IQ internal (keyboard) display: */
//       {
//          if (Disp_Image.count < SwitchRate)
//             DISPLAY = (INT8)Disp_Image.normal_image[Disp_Image.offset];
//          else
//             DISPLAY = (INT8)Disp_Image.blink_image[Disp_Image.offset];
// 
//        /* Increment the offset to get to the next character in the
//           buffer to display.  When the offset is equal to the size of
//           the buffer to be displayed, we have reached the end of the
//           information to be transmitted to the display.  Reset the
//           offset to zero, and increment the count variable which
//           controls the blink ratio.  Reset the count variable to zero
//           when appropriate.  */
// 
//          if (++Disp_Image.offset >= DISPLAY_LENGTH)
//          {
//             Disp_Image.offset = 0;
// 
//             /*
//             ** Calculate SwitchRate based on display content.
//             ** We do this here as we can't afford the overhead for every character!
//             */
// 
//             SwitchRate = SWITCH_RATE;
// 
//             /* do for each display line */
//             for (i = 0; i < 4; i++)
//             {
//                /* do for each char in display line */
//                for (j = (i * DISPLAY_LINE_LENGTH); j < ((i + 1) * DISPLAY_LINE_LENGTH); j++)
//                {
//                   c = Disp_Image.blink_image[j];
// 
//                   /* is this an alternating character */
//                   if ((c != ' ') && (c != Disp_Image.normal_image[j]))
//                   {
//                         /* if we find an alternating character anywhere in the line, slow down the switch rate */
//                         SwitchRate += ALTERNATING_LINE_DELAY;
//                         break;  /* no need to look further */
//                   }
//                }
//             }
// 
//             /* have we finished this switch cycle? */
//             if (++Disp_Image.count >= (SwitchRate * 2))
//             {
//                Disp_Image.count = 0;
//             }
//          }
//       }
//    }
/*--------end change----------------------*/
}

#pragma SECTION UNDO

/***********************************************************************/
/* FUNCTION:  NotFull                                                  */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function returns true if the index passed as the     */
/*           parameter is within the bounds of the current display     */
/*           line.                                                     */
/*                                                                     */
/* RETURNED VALUE: INT16 (boolean)                                     */
/*                                                                     */
/* GLOBALS USED:  Disp_Image                                           */
/*                                                                     */
/***********************************************************************/
static INT16 NotFull(INT16 j)
{
        return ((j < DISPLAY_LENGTH) &&
                (j < (Disp_Image.next_index + DISPLAY_LINE_LENGTH)));
}

/***********************************************************************/
/* FUNCTION:  DoDisplayRamStringAppend                                 */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function appends a string from RAM to the display.   */
/*           The string may contain any number of number format fields.*/
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  Disp_Image                                           */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/***********************************************************************/

static void DoDisplayRamStringAppend(BIT8 *ram_string, va_list *pap)
{
    INT16 i = 0, j, n;
    U_INT16 width, scale;
    BIT8  *source;

    /* recall position to append at */
    j = Disp_Image.next_index;

    /* Scan the string looking for special characters. */
    while (ram_string[i] != '\0')
    {
        switch (ram_string[i])
        {
        case BLINK_CH:
            i++;  /* consume BLINK_CH */

            /* To blink a character on the display, the normal image
               is assigned the character, and the blink image
               is assigned a blank character. */

            if (NotFull(j))
            {
                Disp_Image.blink_image[j] = ' ';
                Disp_Image.normal_image[j++] = ram_string[i];
            }

            i++;
            break;

        case ALTERNATE_CH:
            i++;  /* consume ALTERNATE_CH */

            /* To alternate a character on the display, the normal image
               is assigned the character, and the blink image
               is assigned the alternate character. */

            if (NotFull(j))
            {
                Disp_Image.blink_image[j] = ram_string[i];
                Disp_Image.normal_image[j++] = ram_string[i+1];
            }

            i += 2;
            break;

        case FMT_NUMBER_CH:
            i++;  /* consume FMT_NUMBER_CH */

            /* Get the field width value. */
            width = ram_string[i++];

            /* Get the scale value. */
            scale = ram_string[i++];

            /* format the number into the buffer. */

            /* index of next char after field */
            n = j + ((width > 127) ? (256 - width) : width);

            if (NotFull(n-1))  /* check that last char of field will fit */
            {
                (void)FormatDecimal(Disp_Image.normal_image,
                                    va_arg(*pap, INT32),
                                    j,
                                    width,
                                    scale);
            }

            /* copy the number into the blink_image */
            for (; (j < n) && NotFull(j); j++)
            {
                Disp_Image.blink_image[j] = Disp_Image.normal_image[j];
            }
            break;

        case FMT_HNUMBER_CH:
            i++;  /* consume FMT_HNUMBER_CH */

            /* Get the field width value. */
            width = ram_string[i++];

            /* format the number into the buffer. */

            /* index of next char after field */
            n = j + ((width > 127) ? (256 - width) : width);

            if (NotFull(n-1))  /* check that last char of field will fit */
            {
                (void)FormatHexadecimal(va_arg(*pap, INT32),
                                        &(Disp_Image.normal_image[j]),
                                        width);
            }

            /* copy the number into the blink_image */
            for (; (j < n) && NotFull(j); j++)
            {
                Disp_Image.blink_image[j] = Disp_Image.normal_image[j];
            }
            break;

        case NUM_BLANKS_CH:
            i++;  /* consume NUM_BLANKS_CH */

            /* next character indicates the number of blanks to insert */
            for (n = 0; (n < ram_string[i]) && NotFull(j); n++)
            {
                Disp_Image.normal_image[j] = ' ';
                Disp_Image.blink_image[j++] = ' ';
            }

            i++;  /* consume blank count */
            break;

        case FMT_STRING_CH:
            i++;  /* consume FMT_STRING_CH */

            source = va_arg( *pap, BIT8 * );
            width = 0;      /* index into source substring */

            /* next character indicates the number of chars to insert */
            for (n = 0; (n < ram_string[i]) && NotFull(j); n++)
            {

                if ( *(BIT8 *)(source + width) == 0 )
                {
                   Disp_Image.normal_image[j] = ' ';
                   Disp_Image.blink_image[j++] = ' ';
                }
                else
                {
                   Disp_Image.normal_image[j] = Disp_Image.blink_image[j] =  *(BIT8 *)(source + width);
                   j++;
                }

                width++;
            }

            i++;  /* consume blank count */
            break;

        case FMT_STRING_NO_PAD_CH:
            i++;  /* consume FMT_STRING_NO_PAD_CH */

            source = va_arg( *pap, BIT8 * );
            width = 0;      /* index into source substring */

            /* next character indicates the number of chars to insert */
            for (n = 0; (n < ram_string[i]) && NotFull(j); n++)
            {

                if ( *(BIT8 *)(source + width) == 0 ) break;

                Disp_Image.normal_image[j] = Disp_Image.blink_image[j] =  *(BIT8 *)(source + width);
                j++;

                width++;
            }

            i++;  /* consume blank count */
            break;

        case NEWLINE_CH:
            i++;  /* consume NEWLINE_CH */

            /* blank-fill current line*/
            for (; NotFull(j); j++)
            {
                Disp_Image.normal_image[j] = ' ';
                Disp_Image.blink_image[j] = ' ';
            }

            /* advance index to next empty line */
            Disp_Image.next_index += DISPLAY_LINE_LENGTH;
            break;

        default:
            /* Normal character, so just copy to display */
            if (NotFull(j))
            {
                Disp_Image.normal_image[j] = ram_string[i];
                Disp_Image.blink_image[j++] = ram_string[i];
            }

            i++;
            break;
        }
    }

    /* advance index to next empty line */
    Disp_Image.next_index += DISPLAY_LINE_LENGTH;

    /* pad remaining digits in entire display with blanks */
    for (; j < DISPLAY_LENGTH; j++)
    {
        Disp_Image.normal_image[j] = ' ';
        Disp_Image.blink_image[j] = ' ';
    }
}

/***********************************************************************/
/* FUNCTION:  DoDisplayRamString                                       */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function outputs a string from RAM to the display.   */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  Disp_Image                                           */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/***********************************************************************/

static void DoDisplayRamString(BIT8 * ram_string, va_list *pap)
{
    Disp_Image.next_index = 1;          /* reset display line index */
    DoDisplayRamStringAppend(ram_string, pap);
}

/***********************************************************************/
/* FUNCTION:  DisplayRamString                                         */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function outputs a string from RAM to the display.   */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  Disp_Image                                           */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/***********************************************************************/

void DisplayRamString(BIT8 * ram_string, ...)
{
    va_list ap;

    va_start(ap, ram_string);

    Disp_Image.next_index = 1;          /* reset display line index */
    DoDisplayRamStringAppend(ram_string, &ap);

    va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayRomMessage                                        */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number (defined in          */
/*           messages.h) and sends the message corresponding to that   */
/*           number to the display. The function only displays strings */
/*           in ROM.                                                   */
/*                                                                     */
/* RETURNED VALUE: None.                                               */
/*                                                                     */
/* GLOBALS USED: Disp_Image                                            */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/***********************************************************************/

void DisplayRomMessage(U_INT32 msg, ...)
{
    va_list ap;

    va_start(ap, msg);

    PauseMonitor();

    DoDisplayRamString(MessageToString(msg), &ap);

    va_end(ap);
}

void DisplayMsgBriefly(U_INT32 msg, ...)
{
    va_list ap;

    va_start(ap, msg);

    PauseMonitor();

    DoDisplayRamString(MessageToString(msg), &ap);

/*--------begin change by wangwei----------*/
//    EnableErrorTimeout();
/*-------end change------------------------*/
    va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayWarnings                                          */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number (defined in          */
/*           messages.h) and sends the message corresponding to that   */
/*           number to the display following the heading defined in    */
/*           WARNING_TITLE_MSG.                                        */
/*                                                                     */
/* RETURNED VALUE: None.                                               */
/*                                                                     */
/* GLOBALS USED: Disp_Image                                            */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/*               This is implemented as a function rather than a macro */
/*               invoking DisplayTwoRomMessage() for size reasons      */
/*               because of the number of callers.                     */
/*                                                                     */
/***********************************************************************/

void DisplayWarnings(U_INT32 msg, ...)
{
        va_list ap;

        va_start(ap, msg);

        PauseMonitor();
        DoDisplayRamString(MessageToString(WARNING_TITLE_MSG), &ap);
        DoDisplayRamStringAppend(MessageToString(msg), &ap);

        va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayShutdowns                                         */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number (defined in          */
/*           messages.h) and sends the message corresponding to that   */
/*           number to the display following the heading defined in    */
/*           SHUTDOWN_TITLE_MSG.                                       */
/*                                                                     */
/* RETURNED VALUE: None.                                               */
/*                                                                     */
/* GLOBALS USED: Disp_Image                                            */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/*               This is implemented as a function rather than a macro */
/*               invoking DisplayTwoRomMessage() for size reasons      */
/*               because of the number of callers.                     */
/*                                                                     */
/***********************************************************************/

void DisplayShutdowns(U_INT32 msg, ...)
{
        va_list ap;

        va_start(ap, msg);

        PauseMonitor();
        DoDisplayRamString(MessageToString(SHUTDOWN_TITLE_MSG), &ap);
        DoDisplayRamStringAppend(MessageToString(msg), &ap);

        va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayErrors                                            */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number (defined in          */
/*           messages.h) and sends the message corresponding to that   */
/*           number to the display following the heading defined in    */
/*           MSG_ERROR.                                                */
/*                                                                     */
/* RETURNED VALUE: None.                                               */
/*                                                                     */
/* GLOBALS USED: Disp_Image                                            */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/*               This is implemented as a function rather than a macro */
/*               invoking DisplayTwoRomMessage() for size reasons      */
/*               because of the number of callers.                     */
/*                                                                     */
/***********************************************************************/

void DisplayErrors(U_INT32 msg, ...)
{
        va_list ap;

        va_start(ap, msg);

        PauseMonitor();
        DoDisplayRamString(MessageToString(MSG_ERROR), &ap);
        DoDisplayRamStringAppend(MessageToString(msg), &ap);

        va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayRangeErrors                                       */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number (defined in          */
/*           messages.h) and sends the message corresponding to that   */
/*           number to the display following the heading defined in    */
/*           MSG_RANGE_ERROR.                                          */
/*                                                                     */
/* RETURNED VALUE: None.                                               */
/*                                                                     */
/* GLOBALS USED: Disp_Image                                            */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/*               This is implemented as a function rather than a macro */
/*               invoking DisplayTwoRomMessage() for size reasons      */
/*               because of the number of callers.                     */
/*                                                                     */
/***********************************************************************/

void DisplayRangeErrors(U_INT32 msg, ...)
{
        va_list ap;

        va_start(ap, msg);

        PauseMonitor();
        DoDisplayRamString(MessageToString(MSG_RANGE_ERROR), &ap);
        DoDisplayRamStringAppend(MessageToString(msg), &ap);

        va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayNonFatalErrors                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number (defined in          */
/*           messages.h) and sends the message corresponding to that   */
/*           number to the display following the heading defined in    */
/*           NON_FATAL_ERR_TITLE_MSG.                                  */
/*                                                                     */
/* RETURNED VALUE: None.                                               */
/*                                                                     */
/* GLOBALS USED: Disp_Image                                            */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/***********************************************************************/

void DisplayNonFatalErrors(U_INT32 msg, ...)
{
        va_list ap;

        va_start(ap, msg);

        PauseMonitor();
        DoDisplayRamString(MessageToString(NON_FATAL_ERR_TITLE_MSG), &ap);
        DoDisplayRamStringAppend(MessageToString(msg), &ap);

        va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayTwoRomMessage                                     */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: This function takes 2 message numbers and transfers the    */
/*          corresponding messages to the display.                     */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  None.                                                */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/***********************************************************************/

void DisplayTwoRomMessage(U_INT32 msg1, U_INT32 msg2, ...)
{
    va_list ap;

    va_start(ap, msg2);

    PauseMonitor();
    DoDisplayRamString(MessageToString(msg1), &ap);
    DoDisplayRamStringAppend(MessageToString(msg2), &ap);

    va_end(ap);
}

/***********************************************************************/
/* FUNCTION:  DisplayFourRomMessage                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE: This function takes 4 message numbers and transfers the    */
/*          corresponding messages to the display.                     */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  None.                                                */
/*                                                                     */
/* LIMITATIONS:  Handles blinking characters, moving to a new line in  */
/*               the display, number formats, and compressed spaces.   */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/*               Calls PauseMonitor().                                 */
/*                                                                     */
/***********************************************************************/

void DisplayFourRomMessage(U_INT32 msg1, U_INT32 msg2, U_INT32 msg3, U_INT32 msg4, ...)
{
    va_list ap;

    va_start(ap, msg4);

    PauseMonitor();
    DoDisplayRamString(MessageToString(msg1), &ap);
    DoDisplayRamStringAppend(MessageToString(msg2), &ap);
    DoDisplayRamStringAppend(MessageToString(msg3), &ap);
    DoDisplayRamStringAppend(MessageToString(msg4), &ap);

    va_end(ap);
}


/***********************************************************************/
/* FUNCTION: TransferMsg                                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number and up to n numbers, */
/*           and transfers the corresponding message and the numbers   */
/*           into a buffer, usually to the Line buffer for outputting  */
/*           to the display.                                           */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  None.                                                */
/*                                                                     */
/* LIMITATIONS:  Handles number formats, and compressed spaces.        */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/***********************************************************************/

void TransferMsg(U_INT16 msg_number, BIT8 * string, ...)
{

    va_list ap;
    INT16 i = 0, j = 0, n;
    U_INT16 width, scale;
    BIT8  *msg_string, *source;

    va_start(ap, string);

    /* Convert the message number to a string pointer to the message. */

    msg_string =  MessageToString(msg_number);

    /* Scan the message string for special formatting characters. */
    while (msg_string[i] != '\0')
    {
        switch (msg_string[i])
        {
        case NUM_BLANKS_CH:
            i++;  /* consume NUM_BLANKS_CH */

            /* next character indicates the number of blanks to insert */
            for (n = 0; n < msg_string[i]; n++)
            {
                string[j++] = ' ';
            }

            i++;  /* consume blank count */

            break;

        case FMT_NUMBER_CH:
            i++;  /* consume FMT_NUMBER_CH */

            /* Get the field width value. */
            width = msg_string[i++];

            /* Get the scale value. */
            scale = msg_string[i++];

            /* format the number in the buffer. */
            (void)FormatDecimal(string,
                                va_arg(ap, INT32),
                                j,
                                width,
                                scale);

            j += (width > 127) ? (256 - width) : width;
            break;

        case FMT_HNUMBER_CH:
            i++;  /* consume FMT_HNUMBER_CH */

            /* Get the field width value. */
            width = msg_string[i++];

            /* format the number in the buffer. */
            (void)FormatHexadecimal(va_arg(ap, INT32), string + j, width);

            j += (width > 127) ? (256 - width) : width;
            break;

        case FMT_STRING_CH:
            i++;  /* consume FMT_STRING_CH */

            source = va_arg( ap, BIT8 * );  /* pointer into source substring */
            width  = 0;                     /* index   into source substring */

            /* next character indicates the number of chars to insert */
            for (n = 0; (n < msg_string[i]) && NotFull(j); n++)
            {
                if ( *(BIT8 *)(source + width) == 0 )
                {
                   string[j++] = ' ';
                }
                else
                {
                   string[j++] =  *(BIT8 *)(source + width);
                }

                width++;
            }

            i++;  /* consume blank count */
            break;

        case FMT_STRING_NO_PAD_CH:
            i++;  /* consume FMT_STRING_NO_PAD_CH */

            source = va_arg( ap, BIT8 * );  /* pointer into source substring */
            width  = 0;                     /* index   into source substring */

            /* next character indicates the number of chars to insert */
            for (n = 0; (n < msg_string[i]) && NotFull(j); n++)
            {
                if ( *(BIT8 *)(source + width) == 0 ) break;

                string[j++] =  *(BIT8 *)(source + width);

                width++;
            }

            i++;  /* consume blank count */
            break;

        default:
            /* No special formatting:  transfer the character to the string. */
            string[j++] = msg_string[i++];
        }
    }

    /* Null terminate the resulting string. */
    string[j] = '\0';

    va_end(ap);
}

/***********************************************************************/
/* FUNCTION: TransferMsgLeftJustify                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function takes a message number and up to n numbers, */
/*           and transfers the corresponding message and the numbers   */
/*           into a buffer, usually to the Line buffer for outputting  */
/*           to the display.  This differs from TransferMsg in that it */
/*           forces left-justification, ignoring leading whitespace.   */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  None.                                                */
/*                                                                     */
/* LIMITATIONS:  Handles number formats, and compressed spaces.        */
/*                                                                     */
/*               Use of <stdargs.h> assumes that optional number args  */
/*               are all of type INT32!                                */
/*                                                                     */
/***********************************************************************/

void TransferMsgLeftJustify(U_INT16 msg_number, BIT8 * string, ...)
{

    va_list ap;
    INT16 i = 0, j = 0, n;
    U_INT16 width, scale;
    BIT8 *msg_string, SkipBlanks = TRUE, *source;

    va_start(ap, string);

    /* Convert the message number to a string pointer to the message. */
    msg_string = MessageToString(msg_number);

    /* Scan the message string for special formatting characters. */
    while (msg_string[i] != '\0')
    {
        switch (msg_string[i])
        {
        case NUM_BLANKS_CH:
            i++;  /* consume NUM_BLANKS_CH */

            /* next character indicates the number of blanks to insert */
            for (n = 0; (n < msg_string[i]) && !SkipBlanks; n++)
            {
                string[j++] = ' ';
            }

            i++;  /* consume blank count */

            break;

        case FMT_NUMBER_CH:
            i++;  /* consume FMT_NUMBER_CH */

            /* Get the field width value. */
            width = msg_string[i++];

            /* Get the scale value. */
            scale = msg_string[i++];

            /* format the number in the buffer. */
            (void)FormatDecimal(string,
                                va_arg(ap, INT32),
                                j,
                                width,
                                scale);

            j += (width > 127) ? (256 - width) : width;
            SkipBlanks = FALSE;
            break;

        case FMT_HNUMBER_CH:
            i++;  /* consume FMT_HNUMBER_CH */

            /* Get the field width value. */
            width = msg_string[i++];

            /* format the number in the buffer. */
            (void)FormatHexadecimal(va_arg(ap, INT32), string + j, width);

            j += (width > 127) ? (256 - width) : width;
            SkipBlanks = FALSE;
            break;

        case FMT_STRING_CH:
            i++;  /* consume FMT_STRING_CH */

            source = va_arg( ap, BIT8 * );
            width = 0;      /* index into source substring */

            /* next character indicates the number of chars to insert */
            for (n = 0; (n < msg_string[i]) && NotFull(j); n++)
            {

                if ( *(BIT8 *)(source + width) == 0 )
                {
                   string[j++] = ' ';
                }
                else
                {
                   string[j++] =  *(BIT8 *)(source + width);
                }
                width++;
            }

            i++;  /* consume blank count */
            SkipBlanks = FALSE;
            break;

        case FMT_STRING_NO_PAD_CH:
            i++;  /* consume FMT_STRING_NO_PAD_CH */

            source = va_arg( ap, BIT8 * );
            width = 0;      /* index into source substring */

            /* next character indicates the number of chars to insert */
            for (n = 0; (n < msg_string[i]) && NotFull(j); n++)
            {

                if ( *(BIT8 *)(source + width) == 0 ) break;

                string[j++] =  *(BIT8 *)(source + width);

                width++;
            }

            i++;  /* consume blank count */
            SkipBlanks = FALSE;
            break;

        default:
            /* No special formatting:  transfer the character to the string. */
            if (!(SkipBlanks && msg_string[i] == ' '))
            {
                string[j++] = msg_string[i];
                SkipBlanks = FALSE;
            }
            i++;  /* consume character */
        }
    }

    /* Null terminate the resulting string. */
    string[j] = '\0';

    va_end(ap);
}

/***********************************************************************/
/* FUNCTION: Display4Lines                                             */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function displays the format buffer used to output   */
/*           to the display, called Lines.                             */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* GLOBALS USED:  Lines                                                */
/*                                                                     */
/* LIMITATIONS:  Only outputs the Lines format buffer. Does not        */
/*               operate on a generic four line buffer.                */
/*                                                                     */
/***********************************************************************/

void Display4Lines(void)
{
    INT16 j = 1, count = 0, line_num = 0;
    BIT8 *lineptr;

    /* Traverse through each line in the four line buffer. */

    for (line_num = 0; line_num < 4; line_num++)
    {
        /* Count is used for each line buffer, to make sure we don't
           exceed the twenty characters in each line. We will only display
           the first 20 characters. */

        count = 0;

        /* Set lineptr to point to the first character in the current line
           buffer. */

        lineptr = &(Lines[line_num])[0];

        /* Scan the current line buffer and process special formatting
           characters if present. */

        while ((count < DISPLAY_LINE_LENGTH) && (*lineptr != '\0'))
        {
            switch (*lineptr)
            {
            case BLINK_CH: /* The next character should blink when displayed. */
                lineptr++;  /* skip BLINK_CH */
                if (*lineptr != '\0')
                {
                    /* To blink a character, assign the character to the
                       normal image, and a blank character to the blink
                       image. */

                    Disp_Image.blink_image[j] = ' ';
                    Disp_Image.normal_image[j++] = *lineptr++;

                }
                break;

            case ALTERNATE_CH:
                lineptr++;  /* skip ALTERNATE_CH */
                if (*lineptr != '\0')
                {
                    /* To alternate a character on the display, the normal
                       image is assigned the character, and the blink image
                       is assigned the alternate character. */

                    Disp_Image.blink_image[j] = *lineptr++;
                    Disp_Image.normal_image[j++] = *lineptr++;

                }
                break;

            default:
                /* No special formatting. Transfer the character to the
                   display buffers. */

                Disp_Image.blink_image[j] = *lineptr;
                Disp_Image.normal_image[j++] = *lineptr++;

                break;

            }  /* end switch */

            count++;

        }  /* end while loop */

        /* If the current line buffer had less than 20 characters, pad the
           rest of the line to be displayed with blanks. */

        for (; count < DISPLAY_LINE_LENGTH; count++, j++)
        {
            Disp_Image.normal_image[j] = ' ';
            Disp_Image.blink_image[j] = ' ';
        }

    }  /* end for loop */
}

/***********************************************************************/
/* FUNCTION:  InitializeDisplay                                        */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function initializes the keyboard display.           */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void InitializeDisplay(void)
{
    INT16 i;

    /* Make sure the display buffers contain the "home" character as the
       first character, so all strings output will begin at the first
       location in the display. */

    Disp_Image.normal_image[0] = '\014';
    Disp_Image.blink_image[0]  = '\014';

    External_Image.normal_image[0] = '\014';
    External_Image.blink_image[0]  = '\014';

    for (i=1; i<=80; i++)
    {
       Disp_Image.normal_image[i] = ' ';
       Disp_Image.blink_image[i]  = ' ';

       External_Image.normal_image[i] = ' ';
       External_Image.blink_image[i]  = ' ';
    }

    /* The offset value is used to index character by character when
       writing to the display buffers. */

    Disp_Image.offset     = 0;
    External_Image.offset = 0;

    /* Count is used to control the blinking duty cycle. */

    Disp_Image.count     = 0;
    External_Image.count = 0;

    /* Use internal (as opposed to external data comm) display buffers */

    External_Display = FALSE;

    /* Initialize variables needed by the display monitor. */

    Monitor_Clock = 0;
    Monitor_Done = TRUE;
}

/***********************************************************************/
/* FUNCTION:  InitializeDisplayParallel                                */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  This function initializes the display parallel interface  */
/*           in preparation for parallel-mode display operation.       */
/*                                                                     */
/* RETURNED VALUE:  None.                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void InitializeDisplayParallel(void)
{
  /*--------begin change by wangwei----------*/
// #define INITLEN 2
// 
//         INT16 i, timeout;
//         /* initialize display command is "ESC + I" */
//         static const char init[INITLEN] = {"\033\111"};
// 
//         for (i = 0; i < INITLEN; i++)
//         {
//                 timeout = 0x7fff;
//                 while (TRUE)
//                 {
//                         /* timeout if display dead */
//                         if (--timeout < 0)
//                                 return;
// 
//                         /* wait for the display to be not busy */
//                         if ((*PACTL & 0x08) == 0)
//                         {
//                                 DISPLAY = (INT8)init[i];
//                                 break;
//                         }
//                 }
//         }
  /*----------end change------------------------*/
}
